package com.itheima.leetcode.od.b.graph;

import java.util.Arrays;
import java.util.LinkedList;

/**
 * (C卷,100分)- 悄悄话（Java & JS & Python & C）
 * <p>
 * 题目描述
 * <p>
 * 给定一个二叉树，每个节点上站一个人，节点数字表示父节点到该节点传递悄悄话需要花费的时间。
 * <p>
 * 初始时，根节点所在位置的人有一个悄悄话想要传递给其他人，求二叉树所有节点上的人都接收到悄悄话花费的时间。
 * <p>
 * 输入描述
 * <p>
 * 给定二叉树
 * <p>
 * 0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2
 * <p>
 * 注：-1表示空节点
 * <p>
 * <p>
 * <p>
 * 输出描述
 * <p>
 * 返回所有节点都接收到悄悄话花费的时间
 * <p>
 * 38
 * <p>
 * 用例
 * <p>
 * 输入	0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2
 * <p>
 * 输出	38
 * <p>
 * 说明	无
 * <p>
 * 题目解析
 * <p>
 * 题目给的输入信息对照图示来看，应该就是二叉树的层序遍历序列，如下图所示：
 * <p>
 * <p>
 * <p>
 * 层序遍历序列中，父子节点存在如下关系：
 * <p>
 * 如果父节点在序列中的索引是k，则其两个子节点在序列中的索引分别为 2k+1, 2k+2
 * <p>
 * 因此，我们就无需建树操作了。
 * <p>
 * 而悄悄话的传递，其实父节点将自身得到消息的时延累加到其各个子节点上，最终叶子节点中最大的时延值就是：二叉树所有节点上的人都接收到悄悄话花费的时间
 */
public class BFSWhisperPass {
    public static void main(String[] args) {
        /*Scanner sc = new Scanner(System.in);

        int[] times = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();*/

        String input = "0 9 20 -1 -1 15 7 -1 -1 -1 -1 3 2";
        int[] times = Arrays.stream(input.split(" "))
                .mapToInt(Integer::parseInt)
                .toArray();

        System.out.println(getResult(times));
    }

    public static int getResult(int[] times) {
        // 记录题解
        int ans = 0;

        // 根节点的索引是0
        LinkedList<Integer> queue = new LinkedList<>();
        queue.addLast(0);

        while (queue.size() > 0) {
            int fa = queue.poll(); // 父节点索引

            int ch1 = 2 * fa + 1; // 左子节点索引
            int ch2 = 2 * fa + 2; // 右子节点索引

            // fa是否存在左子节点
            boolean ch1_exist = ch1 < times.length && times[ch1] != -1;
            // fa是否存在右子节点
            boolean ch2_exist = ch2 < times.length && times[ch2] != -1;

            // fa如果存在左子节点
            if (ch1_exist) {
                times[ch1] += times[fa];
                queue.offer(ch1);
            }

            // fa如果存在右子节点
            if (ch2_exist) {
                times[ch2] += times[fa];
                queue.offer(ch2);
            }

            // fa是叶子节点
            if (!ch1_exist && !ch2_exist) {
                // 保留叶子节点中最大时延
                ans = Math.max(ans, times[fa]);
            }
        }

        return ans;
    }
}